package com.sdstc.modules.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.ruoyi.common.enums.OrganType;
import com.ruoyi.common.enums.PlanStatus;
import com.ruoyi.common.utils.SecurityUtils;
import com.sdstc.modules.dao.*;
import com.sdstc.modules.dto.AdjustDto;
import com.sdstc.modules.eneity.*;
import com.sdstc.modules.service.PlanService;
import com.sdstc.modules.vo.TempVersionVo;
import com.sdstc.modules.vo.UpdateAdjustVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author ：wk
 * @date ：Created in 2022/11/2 15:32
 */
@Service
public class PlanServiceImpl implements PlanService {

    @Value(value = "${planFile.profile}")
    private String saveFilePath;
    @Autowired
    private PlanDao planDao;

    @Autowired
    private OrgDao orgDao;

    @Autowired
    private PersonPlanDao personPlanDao;

    @Autowired
    private OrganPlanDao organPlanDao;

    @Autowired
    private PersonDao personDao;

    @Autowired
    private PlanFileDao planFileDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PlanEntity savePlan(PlanEntity planEntity){
        String phonenumber = SecurityUtils.getLoginUser().getUser().getPhonenumber();
        SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyyMMddHHmmss" );
        String format = dateFormat.format(new Date());
        planEntity.setPlanCode(phonenumber+format);
        planDao.insert(planEntity);
        String planId = planEntity.getId();
//        saveOrganPersonChange(planEntity.getAdjustInfo());
        String tempVersionId = planEntity.getTempId();

        List<PersonPlanEntity> personPlanEntities = personPlanDao.selectList(new QueryWrapper<PersonPlanEntity>().eq("temp_version_id", tempVersionId).isNotNull("version"));
        List<OrganPlanEntity> organPlanEntities = organPlanDao.selectList(new QueryWrapper<OrganPlanEntity>().eq("temp_version_id", tempVersionId).isNotNull("version"));

        for (PersonPlanEntity personPlanEntity : personPlanEntities) {
            personPlanEntity.setPlanId(planId);
            personPlanDao.updateById(personPlanEntity);
        }

        for (OrganPlanEntity organPlanEntity : organPlanEntities) {
            organPlanEntity.setPlanId(planId);
            organPlanDao.updateById(organPlanEntity);
        }

        List<PlanFileEntity> planFileEntityList = planFileDao.selectList(new QueryWrapper<PlanFileEntity>().eq("temp_version_id", tempVersionId));

        for (PlanFileEntity planFileEntity : planFileEntityList) {
            planFileEntity.setPlanId(planId);
            planFileDao.updateById(planFileEntity);
        }

        return planEntity;
    }

    /**
    *@author: wk
    *@date: 2022/11/9 8:33
    *@description: 方案更新: 同时更新人员、编制计划表
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PlanEntity updatePlan(PlanEntity planEntity){

        planDao.updateById(planEntity);

        String planId = planEntity.getId();
        String tempVersionId = planEntity.getTempId();
        List<PersonPlanEntity> personPlanEntityList = personPlanDao.selectList(new QueryWrapper<PersonPlanEntity>()
                .eq("temp_version_id", tempVersionId)
                .isNull("plan_id")
                .isNotNull("version"));

        for (PersonPlanEntity personPlanEntity : personPlanEntityList) {
            personPlanEntity.setPlanId(planId);
            personPlanDao.updateById(personPlanEntity);
        }

        List<OrganPlanEntity> organPlanEntityList = organPlanDao.selectList(new QueryWrapper<OrganPlanEntity>()
                .eq("temp_version_id", tempVersionId)
                .isNull("plan_id")
                .isNotNull("version"));

        for (OrganPlanEntity organPlanEntity : organPlanEntityList) {
            organPlanEntity.setPlanId(planId);
            organPlanDao.updateById(organPlanEntity);
        }

        return planEntity;

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePlanById(String id){
        planDao.deleteById(id);
    }

    @Override
    public List<PlanEntity> getPlanPage(PlanEntity plan) {
        return planDao.selectList(new QueryWrapper<PlanEntity>()
                .like(StringUtils.isNotBlank(plan.getPlanName()),"plan_name",plan.getPlanName())
                .like(StringUtils.isNotBlank(plan.getPlanCode()),"plan_code",plan.getPlanCode())
                .eq(StringUtils.isNotBlank(plan.getStatus()), "status", plan.getStatus())
                .orderBy(true,false,"effect_time").orderBy(true,false,"create_time"))
                ;
    }

    @Override
    public TempVersionVo getSnowFlakeId(){
        TempVersionVo tempVersionVo = new TempVersionVo();
        tempVersionVo.setTempVersionId(String.valueOf(IdWorker.getId()));
        tempVersionVo.setVersion(1);
        return tempVersionVo;
    }

    /**
    *@author: wk
    *@date: 2022/11/8 13:29
    *@description: 重置：根据tempVersionId，将version为空的删除
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetTempPlan(String tempVersionId){
        if (StringUtils.isBlank(tempVersionId)){
            return;
        }
        List<String> personPlanIds = personPlanDao.selectList(new QueryWrapper<PersonPlanEntity>()
                .eq("temp_version_id", tempVersionId).isNull("version")).stream().map(PersonPlanEntity::getId).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(personPlanIds)){
            personPlanDao.deleteBatchIds(personPlanIds);
        }

        List<String> organPlanIds = organPlanDao.selectList(new QueryWrapper<OrganPlanEntity>()
                .eq("temp_version_id", tempVersionId).isNull("version")).stream().map(OrganPlanEntity::getId).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(organPlanIds)){
            organPlanDao.deleteBatchIds(organPlanIds);
        }

    }

    /**
    *@author: wk
    *@date: 2022/11/4 14:13
    *@description: 编制人员变化新增
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TempVersionVo saveOrganPersonChange(AdjustDto adjustInfo){

        TempVersionVo tempVersionVo = new TempVersionVo();

        List<AdjustDto.Person> personList = adjustInfo.getPersonList();
        List<AdjustDto.Org> orgList = adjustInfo.getOrgList();

        String tempVersionId = adjustInfo.getTempVersionId();

        // todo 批量插入
        if (CollectionUtils.isNotEmpty(personList)){
            for (AdjustDto.Person person : personList) {
                if (StringUtils.isNotBlank(person.getFromOrgId()) && StringUtils.isNotBlank(person.getToOrgId())){
                    PersonPlanEntity personPlanEntity = new PersonPlanEntity();
                    BeanUtils.copyProperties(person,personPlanEntity);
                    personPlanEntity.setFromOrgName(orgDao.selectById(person.getFromOrgId()).getOrgName());
                    personPlanEntity.setToOrgName(orgDao.selectById(person.getToOrgId()).getOrgName());
                    personPlanEntity.setCreateTime(new Date());
//                    personPlanEntity.setDeleted(0);
                    personPlanEntity.setTempVersionId(tempVersionId);
                    personPlanDao.insert(personPlanEntity);
                }
            }
        }

        if (CollectionUtils.isNotEmpty(orgList)){
            for (AdjustDto.Org org : orgList) {
                if (StringUtils.isNotBlank(org.getFromOrgId()) && StringUtils.isNotBlank(org.getToOrgId())){
                    OrganPlanEntity organPlanEntity = new OrganPlanEntity();
                    BeanUtils.copyProperties(org,organPlanEntity);
                    organPlanEntity.setFromOrgName(orgDao.selectById(org.getFromOrgId()).getOrgName());
                    organPlanEntity.setToOrgName(orgDao.selectById(org.getToOrgId()).getOrgName());
                    organPlanEntity.setCreateTime(new Date());
//                    organPlanEntity.setDeleted(0);
                    organPlanEntity.setTempVersionId(tempVersionId);
                    organPlanDao.insert(organPlanEntity);
                }
            }
        }


        if (Objects.nonNull(adjustInfo.getVersion()) && StringUtils.isNotBlank(adjustInfo.getVersion().toString())){
            Integer version = adjustInfo.getVersion();

            List<PersonPlanEntity> personPlanEntities = personPlanDao.selectList(new QueryWrapper<PersonPlanEntity>().eq("temp_version_id", tempVersionId).isNull("version"));
            List<OrganPlanEntity> organPlanEntities = organPlanDao.selectList(new QueryWrapper<OrganPlanEntity>().eq("temp_version_id", tempVersionId).isNull("version"));

            for (PersonPlanEntity personPlanEntity : personPlanEntities) {
                personPlanEntity.setVersion(version);
                personPlanDao.updateById(personPlanEntity);
            }

            for (OrganPlanEntity organPlanEntity : organPlanEntities) {
                organPlanEntity.setVersion(version);
                organPlanDao.updateById(organPlanEntity);
            }

            tempVersionVo.setVersion(version + 1);
        }
        tempVersionVo.setTempVersionId(tempVersionId);

        return tempVersionVo;
    }

    /**
    *@author: wk
    *@date: 2022/11/7 14:04
    *@description: 方案生效
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void effectPlan(String planId){
        // 人员生效
        List<PersonPlanEntity> personPlanEntityList = personPlanDao.selectList(new QueryWrapper<PersonPlanEntity>().eq("plan_id", planId).isNotNull("version"));
        for (PersonPlanEntity personPlanEntity : personPlanEntityList) {
            PersonEntity personEntity = personDao.selectById(personPlanEntity.getPersonId());
            personEntity.setPostBigCateCode(null);
            personEntity.setPostSmallCateCode(null);
            personEntity.setOrgId(personPlanEntity.getToOrgId());
            personDao.updateById(personEntity);
        }

        // 编制生效
        List<OrganPlanEntity> organPlanEntityList = organPlanDao.selectList(new QueryWrapper<OrganPlanEntity>().eq("plan_id", planId).isNotNull("version"));
        for (OrganPlanEntity organPlanEntity : organPlanEntityList) {

            OrganType organType = OrganType.organTypeOf(organPlanEntity.getOrganType());
            OrgEntity fromOrg = orgDao.selectById(organPlanEntity.getFromOrgId());

            //add 2023.11.14 start
            // 临时解决调整时选择子机构 编制总数不改变的问题
            if("2".equals(fromOrg.getOrgLevel())){
                fromOrg = orgDao.selectById(fromOrg.getPid());
            }
            //add 2023.11.14 end

            OrgEntity toOrg = orgDao.selectById(organPlanEntity.getToOrgId());
            Integer changeNum = organPlanEntity.getChangeNum();

            switch (organType) {
                case ADMIN:
                    fromOrg.setOrganizationAdmin(fromOrg.getOrganizationAdmin() + changeNum);
                    toOrg.setOrganizationAdmin(toOrg.getOrganizationAdmin() - changeNum);
                    break;
                case SINGLE:
                    fromOrg.setOrganizationSingle(fromOrg.getOrganizationSingle() + changeNum);
                    toOrg.setOrganizationSingle(toOrg.getOrganizationSingle() - changeNum);
                    break;
                case WORK:
                    fromOrg.setOrganizationWork(fromOrg.getOrganizationWork() + changeNum);
                    toOrg.setOrganizationWork(toOrg.getOrganizationWork() - changeNum);
                    break;
                case CAUSE:
                    fromOrg.setOrganizationCause(fromOrg.getOrganizationCause() + changeNum);
                    toOrg.setOrganizationCause(toOrg.getOrganizationCause() - changeNum);
                    break;
            }

            orgDao.updateById(fromOrg);
            orgDao.updateById(toOrg);

        }

        // 更新方案状态为已生效
        PlanEntity planEntity = planDao.selectById(planId);
        planEntity.setEffectTime(new Date());
        planEntity.setStatus(PlanStatus.Effective.getCode());
        planDao.updateById(planEntity);
    }

    @Override
    public UpdateAdjustVo getNewTempId(String planId) {
        UpdateAdjustVo updateAdjustVo = new UpdateAdjustVo();

        String tempIdInPersonPlan = planDao.queryTempIdInPersonPlan(planId);
        String tempIdInOrgPlan = planDao.queryTempIdInOrgPlan(planId);
        List<PlanFileEntity> tempIdInPlanFile = planFileDao.selectList(new QueryWrapper<PlanFileEntity>().eq("plan_id", planId));
        if (StringUtils.isNotBlank(tempIdInPersonPlan)){
            updateAdjustVo.setTempId(tempIdInPersonPlan);
        }else if (StringUtils.isNotBlank(tempIdInOrgPlan)){
            updateAdjustVo.setTempId(tempIdInOrgPlan);
        }else if (tempIdInPlanFile.size()>0){
            updateAdjustVo.setTempId(tempIdInPlanFile.get(0).getTempVersionId());
        }

        Integer versionInOrgPlan = Objects.nonNull(planDao.queryVersionInOrgPlan(tempIdInPersonPlan)) ? planDao.queryVersionInOrgPlan(tempIdInPersonPlan) : 0;
        Integer versionInPersionPlan = Objects.nonNull(planDao.queryVersionInPersonPlan(tempIdInPersonPlan)) ? planDao.queryVersionInPersonPlan(tempIdInPersonPlan) : 0;
        int max = versionInOrgPlan > versionInPersionPlan ? versionInOrgPlan : versionInPersionPlan;

        updateAdjustVo.setVersion(max+1);
        return updateAdjustVo;
    }

    @Override
    public void saveGenerationFile(MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            String savePath = saveFilePath+ File.separator+file.getOriginalFilename();
            BufferedOutputStream bufferedOutputStream =
                    new BufferedOutputStream(new FileOutputStream(savePath));
            byte[] bytes = new byte[1024];
            int readLen;
            while ((readLen = inputStream.read(bytes)) != -1) {
                bufferedOutputStream.write(bytes, 0, readLen);
            }
            bufferedOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Boolean queryEffectFile(String planId) {
        List<PlanFileEntity> planFileEntities = planFileDao.selectList(new QueryWrapper<PlanFileEntity>().eq("plan_id",planId).eq("file_type", "effect"));
        if (planFileEntities.size()==0){
            return false;
        }
        return true;
    }


}
